library(tidyverse)
library(plotly)
theme_set(theme_minimal())
transitions <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2023/2023-03-28/transitions.csv')
Rows: 37284 Columns: 6── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (4): zone, begin, end, abbreviation
dbl (1): offset
lgl (1): dst
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
timezones <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2023/2023-03-28/timezones.csv')
Rows: 337 Columns: 4── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (2): zone, comments
dbl (2): latitude, longitude
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
timezone_countries <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2023/2023-03-28/timezone_countries.csv')
Rows: 428 Columns: 2── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (2): zone, country_code
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
countries <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2023/2023-03-28/countries.csv')
Rows: 240 Columns: 2── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (2): country_code, place_name
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
world_coordinates <- map_data("world")
current_transition <- transitions |>
filter(begin <= '2023-03-30' , end >= '2023-03-30' ) |>
mutate(hour_offset = offset/3600)
combined_timezones <- timezone_countries |>
left_join(timezones , by='zone') |>
left_join(countries , by='country_code') |>
left_join(current_transition , by='zone') |>
mutate(comments = ifelse(is.na(comments) , '' , comments) ,
abbev = ifelse(substr(abbreviation , 0 ,1) %in% c('-' , '+' , '0') , '' , abbreviation ) ,
daylight = ifelse(dst == 'TRUE' , 'DST' , ' '))
# geo styling
g <- list(
scope = 'world',
projection = list(type = 'robinson'),
framecolor = 'dodgerblue',
showland = TRUE,
showocean = TRUE,
showcountries = TRUE,
landcolor = '#35CE8D',
coastlinecolor = toRGB("white"),
countrycolor = toRGB("white"),
resolution = 50,
lonaxis = list(showgrid = TRUE, dtick=10, gridcolor='black' , gridwidth=0.25)
)
annot_dat <- data.frame(lat=0 , long=1 ,
text="<br><b>Data: </b>IANA tz database #TidyTuesday <b>Map: </b>Nat Rivera @Itsnatrivera")
fig <- plot_geo(combined_timezones, lat = ~latitude, lon = ~longitude, width = 900, height = 550) |>
add_markers( text = ~(paste( paste0(zone , ' ' , daylight), place_name,
paste0(abbev , ' Offset: ' , hour_offset) ,
comments, sep = "<br>") ), hoverinfo = "text" ,
color = I('#4C4B63') , symbol = I("square"), size = I(6) ) |>
add_annotations(data = annot_dat , y = ~lat, x = ~long , text = ~text , inherit = FALSE , showarrow = FALSE) |>
layout(title = paste0('<br>' , '<b>Timezones Around the World</b><br>' , 'Markers are at Principal Locations'),
geo = g )
fig
plt_map <- ggplot() +
geom_map(data = world_coordinates, map = world_coordinates, aes( long, lat, map_id = region ),
color = "black", fill='#007500' , linewidth = 0.2) +
geom_point(data=combined_timezones , aes(x=longitude, y=latitude) , color='dodgerblue' , show.legend = FALSE) +
theme(
panel.grid.major = element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
plot.caption = element_text()
)
Warning: Ignoring unknown aesthetics: x and y
#p <- ggplotly(plt_map)
#p
#ggplotly(plt_map)
plt_map

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShwbG90bHkpCgp0aGVtZV9zZXQodGhlbWVfbWluaW1hbCgpKQoKYGBgCgoKCgpgYGB7cn0KCnRyYW5zaXRpb25zIDwtIHJlYWRyOjpyZWFkX2NzdignaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Jmb3JkYXRhc2NpZW5jZS90aWR5dHVlc2RheS9tYXN0ZXIvZGF0YS8yMDIzLzIwMjMtMDMtMjgvdHJhbnNpdGlvbnMuY3N2JykKdGltZXpvbmVzIDwtIHJlYWRyOjpyZWFkX2NzdignaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3Jmb3JkYXRhc2NpZW5jZS90aWR5dHVlc2RheS9tYXN0ZXIvZGF0YS8yMDIzLzIwMjMtMDMtMjgvdGltZXpvbmVzLmNzdicpCnRpbWV6b25lX2NvdW50cmllcyA8LSByZWFkcjo6cmVhZF9jc3YoJ2h0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9yZm9yZGF0YXNjaWVuY2UvdGlkeXR1ZXNkYXkvbWFzdGVyL2RhdGEvMjAyMy8yMDIzLTAzLTI4L3RpbWV6b25lX2NvdW50cmllcy5jc3YnKQpjb3VudHJpZXMgPC0gcmVhZHI6OnJlYWRfY3N2KCdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcmZvcmRhdGFzY2llbmNlL3RpZHl0dWVzZGF5L21hc3Rlci9kYXRhLzIwMjMvMjAyMy0wMy0yOC9jb3VudHJpZXMuY3N2JykKCgp3b3JsZF9jb29yZGluYXRlcyA8LSBtYXBfZGF0YSgid29ybGQiKQpgYGAKCgoKYGBge3J9CmN1cnJlbnRfdHJhbnNpdGlvbiA8LSB0cmFuc2l0aW9ucyB8PgogIGZpbHRlcihiZWdpbiA8PSAnMjAyMy0wMy0zMCcgICwgZW5kID49ICcyMDIzLTAzLTMwJyApIHw+CiAgbXV0YXRlKGhvdXJfb2Zmc2V0ID0gb2Zmc2V0LzM2MDApIApgYGAKCgpgYGB7cn0KY29tYmluZWRfdGltZXpvbmVzIDwtIHRpbWV6b25lX2NvdW50cmllcyB8PgogIGxlZnRfam9pbih0aW1lem9uZXMgLCBieT0nem9uZScpIHw+CiAgbGVmdF9qb2luKGNvdW50cmllcyAsIGJ5PSdjb3VudHJ5X2NvZGUnKSB8PgogIGxlZnRfam9pbihjdXJyZW50X3RyYW5zaXRpb24gLCBieT0nem9uZScpIHw+CiAgbXV0YXRlKGNvbW1lbnRzID0gaWZlbHNlKGlzLm5hKGNvbW1lbnRzKSAsICcnICwgY29tbWVudHMpICwgCiAgICAgICAgIGFiYmV2ID0gaWZlbHNlKHN1YnN0cihhYmJyZXZpYXRpb24gLCAwICwxKSAlaW4lIGMoJy0nICwgJysnICwgJzAnKSAsICcnICwgYWJicmV2aWF0aW9uICkgLCAKICAgICAgICAgZGF5bGlnaHQgPSBpZmVsc2UoZHN0ID09ICdUUlVFJyAsICdEU1QnICwgJyAnKSkKICAKYGBgCgoKCgoKYGBge3J9CiMgZ2VvIHN0eWxpbmcKZyA8LSBsaXN0KAogIHNjb3BlID0gJ3dvcmxkJywKICBwcm9qZWN0aW9uID0gbGlzdCh0eXBlID0gJ3JvYmluc29uJyksCiAgZnJhbWVjb2xvciA9ICdkb2RnZXJibHVlJywKICBzaG93bGFuZCA9IFRSVUUsCiAgc2hvd29jZWFuID0gVFJVRSwKICBzaG93Y291bnRyaWVzID0gVFJVRSwKICBsYW5kY29sb3IgPSAnIzM1Q0U4RCcsCiAgY29hc3RsaW5lY29sb3IgPSB0b1JHQigid2hpdGUiKSwKICBjb3VudHJ5Y29sb3IgPSB0b1JHQigid2hpdGUiKSwKICByZXNvbHV0aW9uID0gNTAsCiAgbG9uYXhpcyA9IGxpc3Qoc2hvd2dyaWQgPSBUUlVFLCBkdGljaz0xMCwgZ3JpZGNvbG9yPSdibGFjaycgLCBncmlkd2lkdGg9MC4yNSkKICApCgphbm5vdF9kYXQgPC0gZGF0YS5mcmFtZShsYXQ9MCAsIGxvbmc9MSAsIAogICAgICAgICAgICAgICAgICAgICAgICB0ZXh0PSI8YnI+PGI+RGF0YTogPC9iPklBTkEgdHogZGF0YWJhc2UgI1RpZHlUdWVzZGF5ICA8Yj5NYXA6IDwvYj5OYXQgUml2ZXJhIEBJdHNuYXRyaXZlcmEiKQoKZmlnIDwtIHBsb3RfZ2VvKGNvbWJpbmVkX3RpbWV6b25lcywgbGF0ID0gfmxhdGl0dWRlLCBsb24gPSB+bG9uZ2l0dWRlLCAgd2lkdGggPSA5MDAsIGhlaWdodCA9IDU1MCkgfD4gCiAgYWRkX21hcmtlcnMoIHRleHQgPSB+KHBhc3RlKCAgcGFzdGUwKHpvbmUgLCAnICAgJyAsIGRheWxpZ2h0KSwgcGxhY2VfbmFtZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZTAoYWJiZXYgLCAnICBPZmZzZXQ6ICcgLCBob3VyX29mZnNldCkgLCAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tZW50cywgc2VwID0gIjxicj4iKSApLCAgaG92ZXJpbmZvID0gInRleHQiICwKICAgICAgICAgICAgICAgY29sb3IgPSBJKCcjNEM0QjYzJykgLCBzeW1ib2wgPSBJKCJzcXVhcmUiKSwgc2l6ZSA9IEkoNikgICkgfD4gCiAgYWRkX2Fubm90YXRpb25zKGRhdGEgPSBhbm5vdF9kYXQgLCB5ID0gfmxhdCwgeCA9IH5sb25nICwgdGV4dCA9IH50ZXh0ICwgaW5oZXJpdCA9IEZBTFNFICwgc2hvd2Fycm93ID0gRkFMU0UpIHw+CiAgbGF5b3V0KHRpdGxlID0gcGFzdGUwKCc8YnI+JyAsICc8Yj5UaW1lem9uZXMgQXJvdW5kIHRoZSBXb3JsZDwvYj48YnI+JyAsICdNYXJrZXJzIGFyZSBhdCBQcmluY2lwYWwgTG9jYXRpb25zJyksIAogICAgICAgICBnZW8gPSBnICApCgogCmZpZwpgYGAKCgoKCgoKCmBgYHtyfQpwbHRfbWFwIDwtIGdncGxvdCgpICsKICBnZW9tX21hcChkYXRhID0gd29ybGRfY29vcmRpbmF0ZXMsIG1hcCA9IHdvcmxkX2Nvb3JkaW5hdGVzLCBhZXMoICBsb25nLCBsYXQsIG1hcF9pZCA9IHJlZ2lvbiApLAoJY29sb3IgPSAiYmxhY2siLCBmaWxsPScjMDA3NTAwJyAsICBsaW5ld2lkdGggPSAwLjIpICsKICBnZW9tX3BvaW50KGRhdGE9Y29tYmluZWRfdGltZXpvbmVzICwgYWVzKHg9bG9uZ2l0dWRlLCB5PWxhdGl0dWRlKSAsIGNvbG9yPSdkb2RnZXJibHVlJyAsIHNob3cubGVnZW5kID0gRkFMU0UpICsKICB0aGVtZSgKICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLng9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpY2tzLnk9ZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KCkKICAgICkKCiNwIDwtIGdncGxvdGx5KHBsdF9tYXApCiNwCiNnZ3Bsb3RseShwbHRfbWFwKQpwbHRfbWFwCmBgYAoKCgoKCgoKCgoKCgoKCgo=